package gm.server.virtual.simulator2D;

import com.sun.scenario.scenegraph.SGGroup;
import com.sun.scenario.scenegraph.SGShape;
import com.sun.scenario.scenegraph.SGTransform;
import gm.GmLog;
import gm.server.Arm;
import gm.server.Head;
import gm.server.WrongPositionException;
import gm.server.geom.Vector2;
import java.awt.Color;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;

/**
 * Fej komponens.
 *
 * @author imruf84
 */
public class HeadComponent extends Head {

    /**
     * Síkidom transzformáció mátrixa.
     */
    final SGTransform.Affine transform = SGTransform.createAffine(null, null);
    /**
     * Csukló síkidomja.
     */
    final SGShape shape = new SGShape();
    /**
     * Transzformáció csoport.
     */
    final SGGroup transformGroup = new SGGroup();
    /**
     * Komponens.
     */
    final SGGroup component = new SGGroup();
    /**
     * Elforgatás.
     */
    private double rotation = 0;

    /**
     * Konstruktor.
     *
     * @param arm1 első kar
     * @param arm2 második kar
     */
    public HeadComponent(Arm arm1, Arm arm2) {
        super(arm1, arm2);
        createComponent();
    }

    /**
     * Komponens létrehozása.
     */
    private void createComponent() {

        double r = 10;

        shape.setShape(new Ellipse2D.Double(-r / 2, -r / 2, r, r));
        shape.setFillPaint(new Color(1f, 1f, 0, 1f));
        shape.setAntialiasingHint(RenderingHints.VALUE_ANTIALIAS_ON);

        transformGroup.add(shape);
        transform.setChild(transformGroup);
        component.add(transform);

        updateTransform();
    }

    /**
     * Transzformáció frissítése.
     */
    private void updateTransform() {
        AffineTransform t = new AffineTransform();
        t.setToIdentity();
        try {
            Vector2 gPos = calculatePositionGlobal();
            t.rotate(getRotation());
            t.translate(gPos.x, gPos.y);
            transform.setAffine(t);
        } catch (WrongPositionException ex) {
            GmLog.printError(ex);
        }

        // Karok transzformációinak a frissítése.
        try {
            Vector2 lPos = calculatePositionLocal();
            Vector2 nutPos1 = new Vector2(getArm1().getNut().getRod().getPosition(), getArm1().getNut().calculatePositionAbsolute());
            double angle1 = lPos.sub(nutPos1).angle() - Math.PI / 2d;
            getArm1Component().setRotation(angle1);

            Vector2 nutPos2 = new Vector2(getArm2().getNut().getRod().getPosition(), getArm2().getNut().calculatePositionAbsolute());
            double angle2 = lPos.sub(nutPos2).angle() - Math.PI / 2d;
            getArm2Component().setRotation(angle2);
        } catch (WrongPositionException ex) {
            GmLog.printError(ex);
        }
    }

    /**
     * Pozíció frissítése.
     */
    public void updatePosition() {
        updateTransform();
    }

    /**
     * Komponens lekérdezése.
     *
     * @return komponens
     */
    public SGGroup getComponent() {
        return component;
    }

    /**
     * Beszúrás gyermekként.
     *
     * @param child gyermek
     */
    public void appendChild(SGGroup child) {
        transformGroup.add(child);
    }

    /**
     * Első kar komponens lekérdezése.
     *
     * @return első kar komponens
     */
    public ArmComponent getArm1Component() {
        return (ArmComponent) getArm1();
    }

    /**
     * Második kar komponens lekérdezése.
     *
     * @return második kar komponens
     */
    public ArmComponent getArm2Component() {
        return (ArmComponent) getArm2();
    }

    /**
     * Forgatás megadása.
     *
     * @param rotation forgatás
     */
    public void setRotation(double rotation) {
        this.rotation = rotation;
    }

    /**
     * Forgatás lekérdezése.
     *
     * @return forgatás szöge
     */
    public double getRotation() {
        return rotation;
    }

}
